{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "fb1c2af4",
   "metadata": {},
   "source": [
    "Variables store information that can be manipulated by the program.\n",
    "Fortran is a _strongly typed_ language, which means that each variable\n",
    "must have a type.\n",
    "\n",
    "There are 5 built-in data types in Fortran:\n",
    "\n",
    "* `integer` -- for data that represent whole numbers, positive or negative\n",
    "* `real` -- for floating-point data (not a whole number)\n",
    "* `complex` -- pair consisting of a real part and an imaginary part\n",
    "* `character` -- for text data\n",
    "* `logical` -- for data that represent boolean (true or false) values\n",
    "\n",
    "Before we can use a variable, we must _declare_ it; this tells the compiler\n",
    "the variable type and any other variable attributes.\n",
    "\n",
    "{% include note.html content=\"Fortran is a _statically typed_ language, which means the type of each\n",
    "variable is fixed when the program is compiled---variable types cannot change while the program is running.\" %}\n",
    "\n",
    "## Declaring variables\n",
    "\n",
    "The syntax for declaring variables is:\n",
    "\n",
    "```\n",
    "<variable_type> :: <variable_name>\n",
    "```\n",
    "\n",
    "where `<variable_type>` is one of the built-in variable types listed above and\n",
    "`<variable_name>` is the name that you would like to call your variable.\n",
    "\n",
    "Variable names must start with a letter and can consist of letters, numbers and underscores.\n",
    "In the following example we declare a variable for each of the built-in types.\n",
    "\n",
    "__Example:__ variable declaration"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d0122ca6",
   "metadata": {},
   "outputs": [],
   "source": [
    "integer :: amount\n",
    "real :: pi\n",
    "! complex :: frequency\n",
    "! character :: initial\n",
    "logical :: isOkay"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ff8357ec",
   "metadata": {},
   "source": [
    "{% include note.html content=\"Fortran code is __case-insensitive__; you don't have to worry about the\n",
    "capitalisation of your variable names, but it's good practice to keep it consistent.\" %}\n",
    "\n",
    "Note the additional statement at the beginning of the program: `implicit none`.\n",
    "This statement tells the compiler that all variables will be explicitly declared; without \n",
    "this statement variables will be implicitly typed according to the letter they begin with.\n",
    "\n",
    "{% include important.html content=\"Always use the `implicit none` statement at\n",
    "the beginning of each program and procedure. Implicit typing is considered bad practice in \n",
    "modern programming since it hides information leading to more program errors.\" %}\n",
    "\n",
    "\n",
    "Once we have declared a variable, we can assign and reassign values to it using the assignment operator `=`.\n",
    "\n",
    "__Example:__ variable assignment"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2f235bec",
   "metadata": {},
   "outputs": [],
   "source": [
    "amount = 10\n",
    "pi = 3.1415927\n",
    "! frequency = (1.0, -0.5)\n",
    "! initial = 'A'\n",
    "isOkay = .false."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d125bf4e",
   "metadata": {},
   "source": [
    "Characters are surrounded by either single (`'`) or double quotes (`\"`).\n",
    "\n",
    "Logical or boolean values can be either `.true.` or `.false.`.\n",
    "\n",
    "{% include important.html title=\"Watch out\" content=\"for assignment at declaration: `integer :: amount = 1`. \n",
    "__This is NOT a normal initialisation;__ it implies the `save` attribute which means that the variable retains\n",
    "its value between procedure calls. Good practice is to initialise your variables separately to their declaration.\" %}\n",
    "\n",
    "\n",
    "## Standard input / output\n",
    "\n",
    "In our _Hello World_ example, we printed text to the command window.\n",
    "This is commonly referred to as writing to `standard output` or `stdout`.\n",
    "\n",
    "We can use the `print` statement introduced earlier to print variable values to `stdout`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "be177117",
   "metadata": {},
   "outputs": [],
   "source": [
    "print *, 'The value of amount (integer) is: ', amount\n",
    "print *, 'The value of pi (real) is: ', pi\n",
    "! print *, 'The value of frequency (complex) is: ', frequency\n",
    "! print *, 'The value of initial (character) is: ', initial\n",
    "print *, 'The value of isOkay (logical) is: ', isOkay"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f83f2020",
   "metadata": {},
   "source": [
    "In a similar way, we can read values from the command window\n",
    "using the `read` statement:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8bb2ed6b",
   "metadata": {},
   "outputs": [],
   "source": [
    "integer :: age\n",
    "\n",
    "print *, 'Please enter your age: 5'\n",
    "! read(*,*) age\n",
    "age = 5\n",
    "print *, 'Your age is: ', age"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3dc90013",
   "metadata": {},
   "source": [
    "This input source is commonly referred to as `standard input` or `stdin`.\n",
    "\n",
    "\n",
    "## Expressions\n",
    "The usual set of arithmetic operators are available, listed in order or precedence:\n",
    "\n",
    "| Operator &nbsp;  | Description    |\n",
    "|:----------------:|----------------|\n",
    "| `**`             | Exponent       |\n",
    "| `*`              | Multiplication |\n",
    "| `/ `             | Division       |\n",
    "| `+`              | Addition       |\n",
    "| `-`              | Subtraction    |\n",
    "\n",
    "<br>\n",
    "\n",
    "__Example:__"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6ea92158",
   "metadata": {},
   "outputs": [],
   "source": [
    "real :: pi\n",
    "real :: radius\n",
    "real :: height\n",
    "real :: area\n",
    "real :: volume\n",
    "\n",
    "pi = 3.1415927\n",
    "\n",
    "print *, 'Enter cylinder base radius:'\n",
    "! read(*,*) radius\n",
    "radius = 20\n",
    "\n",
    "print *, 'Enter cylinder height:'\n",
    "!read(*,*) height\n",
    "height = 14\n",
    "\n",
    "area = pi * radius**2.0\n",
    "volume = area * height\n",
    "\n",
    "print *, 'Cylinder radius is: ', radius\n",
    "print *, 'Cylinder height is: ', height\n",
    "print *, 'Cylinder base area is: ', area\n",
    "print *, 'Cylinder volume is: ', volume"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "31793287",
   "metadata": {},
   "source": [
    "## Floating-point precision\n",
    "\n",
    "The desired floating-point precision can be explicitly declared using a `kind` parameter.\n",
    "The `iso_fortran_env` intrinsic module provides `kind` parameters for the common 32-bit and 64-bit floating-point types.\n",
    "\n",
    "__Example:__ explicit real `kind`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3b5c2399",
   "metadata": {},
   "outputs": [],
   "source": [
    "! use, intrinsic :: iso_fortran_env, only: sp=>real32, dp=>real64\n",
    "! real(sp) :: float32\n",
    "! real(dp) :: float64\n",
    "\n",
    "! float32 = 1.0_sp  ! Explicit suffix for literal constants\n",
    "! float64 = 1.0_dp"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "14f447ac",
   "metadata": {},
   "source": [
    "{% include important.html content=\"Always use a `kind` suffix for floating-point literal constants.\" %}\n",
    "\n",
    "__Example:__ C-interoperable `kind`s"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3b2baee7",
   "metadata": {},
   "outputs": [],
   "source": [
    "!use, intrinsic :: iso_c_binding, only: sp=>c_float, dp=>c_double\n",
    "!real(sp) :: float32\n",
    "!real(dp) :: float64"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "48bf4d32",
   "metadata": {},
   "source": [
    "In the next part we will learn how to use arrays for storing more than one\n",
    "value in a variable."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Fortran",
   "language": "fortran",
   "name": "fortran"
  },
  "language_info": {
   "file_extension": ".f90",
   "mimetype": "text/x-fortran",
   "name": "fortran",
   "version": "2018"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
